using System.Web.Mvc;
using AgileBoard.Core;
using AgileBoard.Web.Controllers.ViewModel;
using SharpArch.Core.PersistenceSupport;
using System.Collections.Generic;
using SharpArch.Web.NHibernate;

namespace AgileBoard.Web.Controllers
{
    [HandleError]
    public class ProjectsController : Controller
    {
        public ProjectsController(IRepository<Project> projectRepository, UserProfile userProfile)
        {
            this.projectRepository = projectRepository;
            this.userProfile = userProfile;
        }

        [Transaction]
        public ActionResult Index() {

            IList<Project> projects = projectRepository.GetAll();
            return View(projects);
        }

        [Transaction]
        public ActionResult Select(int id) {
            var project = projectRepository.Get(id);

            userProfile.ProjectId = project.Id;
            userProfile.ProjectName = project.Name;

            return RedirectToAction("Current", "board");
        }

        public ActionResult Create() {
            ProjectFormViewModel viewModel = ProjectFormViewModel.CreateProjectFormViewModel();
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Project project) {
            if (ViewData.ModelState.IsValid && project.IsValid()) {

                var fullProject = ProjectFactory.Create();
                fullProject.Name = project.Name;
                projectRepository.SaveOrUpdate(fullProject);

                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = 
					"The project was successfully created.";
                return RedirectToAction("Index");
            }

            ProjectFormViewModel viewModel = ProjectFormViewModel.CreateProjectFormViewModel();
            viewModel.Project = project;
            return View(viewModel);
        }

        [Transaction]
        public ActionResult Edit(int id) {
            ProjectFormViewModel viewModel = ProjectFormViewModel.CreateProjectFormViewModel();
            viewModel.Project = projectRepository.Get(id);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Project project) {
            Project projectToUpdate = projectRepository.Get(project.Id);
            TransferFormValuesTo(projectToUpdate, project);

            if (ViewData.ModelState.IsValid && project.IsValid()) {
                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = 
					"The project was successfully updated.";
                return RedirectToAction("Index");
            }
            else {
                projectRepository.DbContext.RollbackTransaction();

				ProjectFormViewModel viewModel = ProjectFormViewModel.CreateProjectFormViewModel();
				viewModel.Project = project;
				return View(viewModel);
            }
        }

        private void TransferFormValuesTo(Project projectToUpdate, Project projectFromForm) {
			projectToUpdate.Name = projectFromForm.Name;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id) {
            string resultMessage = "The project was successfully deleted.";
            Project projectToDelete = projectRepository.Get(id);

            if (projectToDelete != null) {
                projectRepository.Delete(projectToDelete);

                try {
                    projectRepository.DbContext.CommitChanges();
                }
                catch {
                    resultMessage = "A problem was encountered preventing the project from being deleted. " +
						"Another item likely depends on this project.";
                    projectRepository.DbContext.RollbackTransaction();
                }
            }
            else {
                resultMessage = "The project could not be found for deletion. It may already have been deleted.";
            }

            TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = resultMessage;
            return RedirectToAction("Index");
        }

		/// <summary>
		/// Holds data to be passed to the Project form for creates and edits
		/// </summary>
        public class ProjectFormViewModel
        {
            private ProjectFormViewModel() { }

			/// <summary>
			/// Creation method for creating the view model. Services may be passed to the creation 
			/// method to instantiate items such as lists for drop down boxes.
			/// </summary>
            public static ProjectFormViewModel CreateProjectFormViewModel() {
                ProjectFormViewModel viewModel = new ProjectFormViewModel();
                
                return viewModel;
            }

            public Project Project { get; internal set; }
        }

        private readonly IRepository<Project> projectRepository;
        private readonly UserProfile userProfile;
    }
}
